package com.zhang.gulimall.seckill.service;

import com.alibaba.fastjson.JSON;
import com.zhang.gulimall.common.utils.R;
import com.zhang.gulimall.seckill.feign.CouponFeign;
import com.zhang.gulimall.seckill.feign.ProductFeign;
import com.zhang.gulimall.seckill.vo.SeckillSessionVo;
import com.zhang.gulimall.seckill.vo.SeckillSkuRelationVo;
import com.zhang.gulimall.seckill.vo.SkuInfoVo;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.redisson.client.RedisClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;

@Service
public class SeckillService {
    @Autowired
    CouponFeign couponFeign;
    @Autowired
    ProductFeign productFeign;
    @Autowired
    RedissonClient redissonClient;
    @Autowired
    StringRedisTemplate redisTemplate;
    private final String SESSIONS_CACHE_PREFIX = "seckill:sessions:";
    private final String SKUS_CACHE_PREFIX = "skukill:sessions:";
    private final String SKU_STOCK_SEMAPHORE = "seckill:stock:";

    // 商品上架
    public void sessionUp() {
        R r = couponFeign.last3daySession();
        List<SeckillSessionVo> data = JSON.parseArray(JSON.toJSONString(r.get("data")), SeckillSessionVo.class);
        // 保存活动信息
        saveSessionInfo(data);
        // 保存活动商品信息
        saveSessionSkus(data);
    }

    private void saveSessionInfo(List<SeckillSessionVo> sessions) {
        sessions.forEach(session -> {
            String key = SESSIONS_CACHE_PREFIX + session.getStartTime().getTime() + "-" + session.getEndTime().getTime();
            if (!redisTemplate.hasKey(key)) {
                redisTemplate.opsForList().leftPushAll(key, JSON.toJSONString(session));
            }
        });
    }

    private void saveSessionSkus(List<SeckillSessionVo> sessions) {
        sessions.forEach(session -> {
            List<SeckillSkuRelationVo> skuRelationEntities = session.getSkuRelationEntities();
            skuRelationEntities.forEach(entity -> {
                if (!redisTemplate.hasKey(SKUS_CACHE_PREFIX + session.getId() + "-" + entity.getId())) {
                    R info = productFeign.info(entity.getSkuId());
                    SkuInfoVo skuInfo = JSON.parseObject(JSON.toJSONString(info.get("skuInfo")), SkuInfoVo.class);
                    entity.setSkuInfoVo(skuInfo);
                    entity.setStartTime(session.getStartTime());
                    entity.setEndTime(session.getEndTime());
                    String token = UUID.randomUUID().toString().replace("-", "");
                    entity.setRandomCode(token);

                    RSemaphore semaphore = redissonClient.getSemaphore(SKU_STOCK_SEMAPHORE + token);
                    semaphore.trySetPermits(entity.getSeckillCount());

                    redisTemplate.opsForHash().put(SKUS_CACHE_PREFIX + session.getId() + "-" + entity.getId(),
                            session.getId() + "-" + entity.getId(), JSON.toJSONString(entity));
                }
            });
        });
    }
}
